'use strict';

const chai = require('chai');
const chaiHttp = require('chai-http');
const fs = require('fs');
const path = require('path');
const expect = chai.expect;
const app = require('../app');

chai.use(chaiHttp);

describe('外部模型 API 测试', function () {
    this.timeout(10000); // 延长超时时间

    let token;
    let userId;
    let testModelId;
    const testModelPath = path.join(__dirname, 'test_model.glb');

    // 测试前先登录获取token
    before(async function () {
        // 创建测试账号，如果已存在就登录获取token
        const res = await chai.request(app)
            .post('/api/auth/login')
            .send({
                username: 'testuser',
                password: 'testpassword'
            });

        if (res.status === 200) {
            token = res.body.token;
            userId = res.body.user.id;
        } else {
            // 如果登录失败，可能需要创建账号
            const registerRes = await chai.request(app)
                .post('/api/auth/register')
                .send({
                    username: 'testuser',
                    password: 'testpassword',
                    email: 'test@example.com'
                });

            if (registerRes.status === 201) {
                const loginRes = await chai.request(app)
                    .post('/api/auth/login')
                    .send({
                        username: 'testuser',
                        password: 'testpassword'
                    });
                token = loginRes.body.token;
                userId = loginRes.body.user.id;
            } else {
                throw new Error('无法创建测试账号或登录');
            }
        }
    });

    // 测试结束后清理创建的模型
    after(async function () {
        if (testModelId) {
            try {
                await chai.request(app)
                    .delete(`/api/models/${testModelId}`)
                    .set('Authorization', `Bearer ${token}`);
            } catch (error) {
                console.error('清理测试模型失败:', error);
            }
        }
    });

    // 测试创建外部模型
    it('应该能够创建外部模型', async function () {
        const res = await chai.request(app)
            .post('/api/models/external')
            .set('Authorization', `Bearer ${token}`)
            .send({
                name: '测试外部模型',
                description: '这是一个用于测试的外部模型',
                color: '#FF0000', // 红色
                position: { x: 1, y: 2, z: 3 },
                rotation: { x: 45, y: 0, z: 0 },
                scale: { x: 2, y: 2, z: 2 }
            });

        expect(res).to.have.status(201);
        expect(res.body).to.have.property('status', 201);
        expect(res.body).to.have.property('data');
        expect(res.body.data).to.have.property('model');
        expect(res.body.data.model).to.have.property('id');

        testModelId = res.body.data.model.id;

        // 确保模型类型正确
        const modelRes = await chai.request(app)
            .get(`/api/models/${testModelId}`)
            .set('Authorization', `Bearer ${token}`);

        expect(modelRes).to.have.status(200);
        expect(modelRes.body.data.geometry).to.have.property('type', 'external_model');
        expect(modelRes.body.data.geometry).to.have.property('color', '#FF0000');
        expect(modelRes.body.data.geometry.position).to.deep.include({ x: 1, y: 2, z: 3 });
        expect(modelRes.body.data.geometry.scale).to.deep.include({ x: 2, y: 2, z: 2 });
    });

    // 测试上传外部模型文件
    it('应该能够上传外部模型文件', async function () {
        const res = await chai.request(app)
            .post(`/api/models/${testModelId}/upload`)
            .set('Authorization', `Bearer ${token}`)
            .attach('file', testModelPath);

        expect(res).to.have.status(200);
        expect(res.body).to.have.property('status', 200);
        expect(res.body).to.have.property('data');
        expect(res.body.data).to.have.property('fileId', testModelId);
    });

    // 测试更新外部模型属性
    it('应该能够更新外部模型属性', async function () {
        const res = await chai.request(app)
            .put(`/api/models/${testModelId}/external-model`)
            .set('Authorization', `Bearer ${token}`)
            .send({
                color: '#00FF00', // 绿色
                scale: { x: 3, y: 3, z: 3 },
                position: { x: 5, y: 5, z: 5 }
            });

        expect(res).to.have.status(200);
        expect(res.body).to.have.property('status', 200);
        expect(res.body).to.have.property('message', '外部模型属性更新成功');

        // 再次获取模型确认更新成功
        const modelRes = await chai.request(app)
            .get(`/api/models/${testModelId}`)
            .set('Authorization', `Bearer ${token}`);

        expect(modelRes).to.have.status(200);
        expect(modelRes.body.data.geometry).to.have.property('color', '#00FF00');
        expect(modelRes.body.data.geometry.scale).to.deep.include({ x: 3, y: 3, z: 3 });
        expect(modelRes.body.data.geometry.position).to.deep.include({ x: 5, y: 5, z: 5 });
    });

    // 测试一步完成创建和上传外部模型
    it('应该能够一步完成创建和上传外部模型', async function () {
        // 创建模型数据
        const modelData = JSON.stringify({
            name: '一步创建的测试模型',
            description: '这是通过一步完成创建和上传的测试模型',
            color: '#0000FF', // 蓝色
            scale: { x: 1.5, y: 1.5, z: 1.5 }
        });

        const res = await chai.request(app)
            .post('/api/models/external/upload')
            .set('Authorization', `Bearer ${token}`)
            .field('modelData', modelData)
            .attach('file', testModelPath);

        expect(res).to.have.status(201);
        expect(res.body).to.have.property('status', 201);
        expect(res.body.data).to.have.property('model');
        expect(res.body.data.model).to.have.property('id');

        const newModelId = res.body.data.model.id;

        // 获取模型确认创建成功并且属性正确
        const modelRes = await chai.request(app)
            .get(`/api/models/${newModelId}`)
            .set('Authorization', `Bearer ${token}`);

        expect(modelRes).to.have.status(200);
        expect(modelRes.body.data).to.have.property('name', '一步创建的测试模型');
        expect(modelRes.body.data.geometry).to.have.property('type', 'external_model');
        expect(modelRes.body.data.geometry).to.have.property('color', '#0000FF');
        expect(modelRes.body.data.geometry.scale).to.deep.include({ x: 1.5, y: 1.5, z: 1.5 });

        // 清理新创建的模型
        await chai.request(app)
            .delete(`/api/models/${newModelId}`)
            .set('Authorization', `Bearer ${token}`);
    });

    // 测试下载外部模型文件
    it('应该能够下载外部模型文件', async function () {
        const res = await chai.request(app)
            .get(`/api/models/${testModelId}/download`)
            .set('Authorization', `Bearer ${token}`);

        expect(res).to.have.status(200);
        expect(res).to.have.header('content-type', 'application/octet-stream');
        expect(res).to.have.header('content-disposition');
    });

    // 测试获取模型缩略图
    it('应该能够获取模型缩略图', async function () {
        const res = await chai.request(app)
            .get(`/api/models/${testModelId}/thumbnail`)
            .set('Authorization', `Bearer ${token}`);

        expect(res).to.have.status(200);
        expect(res.body).to.have.property('status', 200);
        expect(res.body.data).to.have.property('thumbnail');
        expect(res.body.data.thumbnail).to.be.a('string');
        expect(res.body.data.thumbnail).to.include('data:image/png;base64,');
    });
}); 